package com.springbootblog.utils;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;

/**
 * 自定义curl类
 */
public class CurlRequest
{
    /**
     * @name CURL POST 请求
     * @param url     接口地址
     * @param list    NameValuePair（简单名称值对节点类型）类似html中的input
     * @param headers 请求头（默认Content-Type：application/x-www-form-urlencoded; charset=UTF-8）
     * 请求示例
        // 设置请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
        // 设置请求参数
        ArrayList<NameValuePair> list = new ArrayList<>();
        list.add(new BasicNameValuePair("indexName", "test"));
        // 发送请求
        String s = CurlRequest.curlPost("http://localhost:7001/java/elastic/indexIsExists", list, headers);
        System.out.println(s);
     */
    public static Map<String, Object> curlPost(String url, ArrayList<NameValuePair> list, Map<String, String> headers)
    {
        String StringResult = "";
        CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        if (list != null && !list.isEmpty())
        {
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Consts.UTF_8);
            httpPost.setEntity(formEntity);
        }
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        if (headers != null && !headers.isEmpty())
        {
            for (String head : headers.keySet())
            {
                httpPost.addHeader(head, headers.get(head));
            }
        }
        CloseableHttpResponse response = null;
        try
        {
            response = closeableHttpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            StringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8);
            EntityUtils.consume(entity);
        }
        catch (Exception e)
        {
            StringResult = "errorException:" + e.getMessage();
            e.printStackTrace();
        }
        finally
        {
            checkObjectIsNull(closeableHttpClient, response);
        }
        return Function.convertJsonToMap(StringResult);
    }

    /**
     * @name 异步 CURL POST 请求
     * @param url     接口地址
     * @param list    NameValuePair（简单名称值对节点类型）类似html中的input
     * @param headers 请求头（默认Content-Type：application/x-www-form-urlencoded; charset=UTF-8）
     * 请求示例
        ArrayList<NameValuePair> asynclist = new ArrayList<>();
        asynclist.add(new BasicNameValuePair("indexName", "test"));
        asynclist.add(new BasicNameValuePair("id", "90"));
        // 设置请求头
        Map<String, String> asyncHeaders = new HashMap<>();
        asyncHeaders.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
        // 发送请求
        Map<String,Object> async = CurlRequest.asyncCurlPost("http://localhost:7001/java/elastic/documentIsExists", asynclist, asyncHeaders);
        System.out.println(async);
        return "我在tessss方法中……";
     */
    public static Map<String, Object> asyncCurlPost(String url, ArrayList<NameValuePair> list, Map<String, String> headers)
    {
        String responseBody = "";
        // 创建异步HTTP客户端
        CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();
        try
        {
            httpClient.start(); // 启动HttpClient

            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 设置请求参数
            if (list != null && !list.isEmpty())
            {
                UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list, Consts.UTF_8);
                httpPost.setEntity(formEntity);
            }
            // 设置请求头
            httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            if (headers != null && !headers.isEmpty())
            {
                for (String head : headers.keySet())
                {
                    httpPost.addHeader(head, headers.get(head));
                }
            }
            // 发送请求并获取Future对象
            Future<HttpResponse> future = httpClient.execute(httpPost, null);

            // 获取响应
            HttpResponse response = future.get();
            responseBody = EntityUtils.toString(response.getEntity());
            System.out.println("Response: " + responseBody);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            System.out.println("请求出错了！");
        }
        finally
        {
            // 关闭HttpClient
            try
            {
                httpClient.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            Map<String, Object> result = new HashMap<>();
            result.put("code", 1);
            result.put("result", "异步请求发送成功！");
            result.put("responseBody", responseBody);
            return result;
        }
    }

    /**
     * @name 组装 GET 请求连接
     * @param url    获取get请求URL地址(无参数/有参)
     * @param params 拼接参数集合
     * @Description get请求URL拼接参数 & URL编码
     * 请求示例
        // 设置请求参数
        Map<String, String> params = new HashMap<>();
        params.put("search", "服务");
        // 获取请求链接
        String appendUrl = CurlRequest.getCurlGetUrl("http://localhost:7001/java/index/getArticleListByCategory?page=1", params);
        System.out.println(appendUrl);
     */
    public static String getCurlGetUrl(String url, Map<String, String> params)
    {
        StringBuffer buffer = new StringBuffer(url);
        if (params != null && !params.isEmpty())
        {
            for (String key : params.keySet())
            {
                if (buffer.indexOf("?") >= 0)
                {
                    buffer.append("&");
                }
                else
                {
                    buffer.append("?");
                }
                String value = "";
                //value = params.get(key);
                try
                {
                     value = URLEncoder.encode(params.get(key), StandardCharsets.UTF_8.name());
                }
                catch (UnsupportedEncodingException e)
                {
                    e.printStackTrace();
                }//*/
                buffer.append(key)
                        .append("=")
                        .append(value);
            }
        }
        return buffer.toString();
    }

    /**
     * @name CURL GET 请求
     * @param url     接口地址
     * @param headers 请求头
     * @Description get请求
     * 请求示例
        // 设置请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
        // 设置请求参数
        Map<String, String> params = new HashMap<>();
        params.put("search", "服务");
        // 获取请求链接
        String appendUrl = CurlRequest.getCurlGetUrl("http://localhost:7001/java/index/getArticleListByCategory?page=1", params);
        System.out.println(appendUrl);
        // 发送请求
        String postData = CurlRequest.curlGet(appendUrl,headers);
        System.out.println(postData);
     */
    public static Map<String, Object> curlGet(String url, Map<String, String> headers)
    {
        String StringResult = "";
        CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        if (headers != null && !headers.isEmpty())
        {
            for (String head : headers.keySet())
            {
                httpGet.addHeader(head, headers.get(head));
            }
        }
        CloseableHttpResponse response = null;
        try
        {
            response = closeableHttpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            StringResult = EntityUtils.toString(entity, StandardCharsets.UTF_8).trim();
            EntityUtils.consume(entity);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            StringResult = "errorException:" + e.getMessage();
        }
        finally
        {
            checkObjectIsNull(closeableHttpClient, response);
        }
        return Function.convertJsonToMap(StringResult);
    }

    /**
     * 判断对象是否为Null
     * @param closeableHttpClient
     * @param response
     */
    private static void checkObjectIsNull(CloseableHttpClient closeableHttpClient, CloseableHttpResponse response)
    {
        if(response != null)
        {
            try
            {
                response.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        if (closeableHttpClient != null)
        {
            try
            {
                closeableHttpClient.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

}
